/*
 * $RCSfile: TableAction.java,v $$
 * $Revision: 1.1 $
 * $Date: 2013-03-19 $
 *
 * Copyright (C) 2008 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.webcat.action;

import java.io.IOException;
import java.io.StringReader;
import java.sql.Connection;
import java.util.List;

import javax.servlet.ServletException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.skin.j2ee.action.BaseAction;
import com.skin.j2ee.annotation.UrlPattern;
import com.skin.j2ee.util.JsonUtil;
import com.skin.webcat.database.ChangeColumn;
import com.skin.webcat.database.ChangeContext;
import com.skin.webcat.database.ChangeIndex;
import com.skin.webcat.database.ChangeTable;
import com.skin.webcat.database.Changeable;
import com.skin.webcat.database.sql.SqlPlus;
import com.skin.webcat.database.sql.SqlResult;
import com.skin.webcat.util.Jdbc;
import com.skin.webcat.util.Sql;
import com.skin.webcat.util.Webcat;

/**
 * <p>Title: TableAction</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public class AlterAction extends BaseAction {
    private static final Logger logger = LoggerFactory.getLogger(AlterAction.class);

    /**
     * @throws ServletException
     * @throws IOException
     */
    @UrlPattern("/webcat/table/drop.html")
    public void drop() throws ServletException, IOException {
        String name = this.getTrimString("name", "");
        String database = this.getTrimString("database", "");
        String tableName = this.getTrimString("tableName", "");
        Connection connection = null;

        if(!Sql.isSqlIdentifier(tableName)) {
            JsonUtil.error(this.request, this.response, 500, "bad table name: " + tableName);
            return;
        }

        try {
            String sql = "drop table " + tableName + ";";
            logger.info("sql: {}", sql);

            connection = Webcat.getConnection(name, database);
            SqlResult sqlResult = SqlPlus.execute(connection, new StringReader(sql));
            JsonUtil.callback(this.request, this.response, sqlResult);
            return;
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            JsonUtil.error(this.request, this.response, 500, "系统错误，请稍后再试！");
        }
        finally {
            Jdbc.close(connection);
        }
    }

    /**
     * @throws ServletException
     * @throws IOException
     */
    @UrlPattern("/webcat/table/rename.html")
    public void rename() throws ServletException, IOException {
        String name = this.getTrimString("name", "");
        String database = this.getTrimString("database", "");
        String oldTableName = this.getTrimString("oldTableName", "");
        String newTableName = this.getTrimString("newTableName", "");
        Connection connection = null;

        if(!Sql.isSqlIdentifier(newTableName)) {
            JsonUtil.error(this.request, this.response, 500, "bad table name: " + newTableName);
            return;
        }

        if(!Sql.isSqlIdentifier(newTableName)) {
            JsonUtil.error(this.request, this.response, 500, "bad table name: " + newTableName);
            return;
        }

        try {
            String sql = "alter table rename " + oldTableName + " " + newTableName + ";";
            logger.info("sql: {}", sql);

            connection = Webcat.getConnection(name, database);
            SqlResult sqlResult = SqlPlus.execute(connection, new StringReader(sql));
            JsonUtil.callback(this.request, this.response, sqlResult);
            return;
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            JsonUtil.error(this.request, this.response, 500, "系统错误，请稍后再试！");
        }
        finally {
            Jdbc.close(connection);
        }
    }

    /**
     * @throws ServletException
     * @throws IOException
     */
    @UrlPattern("/webcat/table/alter.html")
    public void alter() throws ServletException, IOException {
        String name = this.getTrimString("name", "");
        String database = this.getTrimString("database", "");
        String tableDefinition = this.getTrimString("tableDefinition", "");
        String indexDefinition = this.getTrimString("indexDefinition", "");
        String columnDefinition = this.getTrimString("columnDefinition", "");
        String action = this.getTrimString("action", "");
        Connection connection = null;
        SqlResult sqlResult = null;

        try {
            String sql = null;

            if("create".equals(action)) {
                sql = this.getCreateSql(tableDefinition, indexDefinition, columnDefinition);
            }
            else {
                sql = this.getAlterSql(tableDefinition, indexDefinition, columnDefinition);
            }
            logger.debug("alter: {}", sql);

            connection = Webcat.getConnection(name, database);
            sqlResult = SqlPlus.execute(connection, new StringReader(sql));
            JsonUtil.callback(this.request, this.response, sqlResult);
            return;
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            JsonUtil.error(this.request, this.response, 500, e.getMessage());
        }
        finally {
            Jdbc.close(connection);
        }
    }

    /**
     * @throws ServletException
     * @throws IOException
     */
    @UrlPattern("/webcat/table/getCreateSql.html")
    public void getCreateSql() throws ServletException, IOException {
        String tableDefinition = this.getTrimString("tableDefinition", "");
        String indexDefinition = this.getTrimString("indexDefinition", "");
        String columnDefinition = this.getTrimString("columnDefinition", "");

        try {
            String sql = this.getCreateSql(tableDefinition, indexDefinition, columnDefinition);
            JsonUtil.success(this.request, this.response, sql);
            return;
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            JsonUtil.error(this.request, this.response, 500, e.getMessage());
        }
    }

    /**
     * @throws ServletException
     * @throws IOException
     */
    @UrlPattern("/webcat/table/getAlterSql.html")
    public void getAlterSql() throws ServletException, IOException {
        String tableDefinition = this.getTrimString("tableDefinition", "");
        String indexDefinition = this.getTrimString("indexDefinition", "");
        String columnDefinition = this.getTrimString("columnDefinition", "");
        String action = this.getTrimString("action", "");

        try {
            String sql = null;

            if("create".equals(action)) {
                sql = this.getCreateSql(tableDefinition, indexDefinition, columnDefinition);
            }
            else {
                sql = this.getAlterSql(tableDefinition, indexDefinition, columnDefinition);
            }
            JsonUtil.success(this.request, this.response, sql);
            return;
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            JsonUtil.error(this.request, this.response, 500, e.getMessage());
        }
    }

    /**
     * @param tableDefinition
     * @param indexDefinition
     * @param columnDefinition
     * @return String
     */
    private String getCreateSql(String tableDefinition, String indexDefinition, String columnDefinition) {
        ChangeTable changeTable = JSON.parseObject(tableDefinition, ChangeTable.class);
        List<ChangeIndex> indexChangeList = JSON.parseArray(indexDefinition, ChangeIndex.class);
        List<ChangeColumn> columnChangeList = JSON.parseArray(columnDefinition, ChangeColumn.class);
        String message = changeTable.validate();

        if(message == null) {
            message = Changeable.validate(indexChangeList, columnChangeList);
        }

        if(message != null) {
            throw new RuntimeException(message);
        }

        ChangeContext changeContext = new ChangeContext(changeTable, columnChangeList, indexChangeList);
        return changeContext.getCreateSql();
    }

    /**
     * @param tableDefinition
     * @param indexDefinition
     * @param columnDefinition
     * @return String
     */
    private String getAlterSql(String tableDefinition, String indexDefinition, String columnDefinition) {
        ChangeTable changeTable = JSON.parseObject(tableDefinition, ChangeTable.class);
        List<ChangeIndex> indexChangeList = JSON.parseArray(indexDefinition, ChangeIndex.class);
        List<ChangeColumn> columnChangeList = JSON.parseArray(columnDefinition, ChangeColumn.class);
        String message = changeTable.validate();

        if(message == null) {
            message = Changeable.validate(indexChangeList, columnChangeList);
        }

        if(message != null) {
            throw new RuntimeException(message);
        }

        ChangeContext changeContext = new ChangeContext(changeTable, columnChangeList, indexChangeList);
        return changeContext.getAlterSql();
    }
}
